package com.sgcc.nfc.lock.presentation.nfc

import android.nfc.Tag
import android.nfc.TagLostException
import android.nfc.tech.NfcA
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sgcc.nfc.lock.core.nfc.NfcDeviceManager
import com.sgcc.nfc.lock.core.nfc.NfcDeviceManager.Control
import com.sgcc.nfc.lock.core.nfc.NfcDiagnostics
import com.sgcc.nfc.lock.core.nfc.NfcConfig
import com.sgcc.nfc.lock.core.network.NetworkResult
import com.sgcc.nfc.lock.domain.model.NfcOperationParams
import com.sgcc.nfc.lock.domain.model.RoleType
import com.sgcc.nfc.lock.domain.model.Room
import com.sgcc.nfc.lock.domain.model.UserProfile
import com.sgcc.nfc.lock.domain.usecase.AddLockUseCase
import com.sgcc.nfc.lock.domain.usecase.CloseLockUseCase
import com.sgcc.nfc.lock.domain.usecase.FindLockByNfcIdUseCase
import com.sgcc.nfc.lock.domain.usecase.FindLockByNfcIdUseCase.LockAccessResult
import com.sgcc.nfc.lock.domain.usecase.GetProfileUseCase
import com.sgcc.nfc.lock.domain.usecase.GetRoomsUseCase
import com.sgcc.nfc.lock.domain.usecase.OpenLockUseCase
import com.sgcc.nfc.lock.core.nfc.NfcDeviceManager.Result as DeviceResult
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

@HiltViewModel
class NfcOperationViewModel @Inject constructor(
    private val findLockByNfcIdUseCase: FindLockByNfcIdUseCase,
    private val openLockUseCase: OpenLockUseCase,
    private val closeLockUseCase: CloseLockUseCase,
    private val addLockUseCase: AddLockUseCase,
    private val getProfileUseCase: GetProfileUseCase,
    private val getRoomsUseCase: GetRoomsUseCase,
    savedStateHandle: SavedStateHandle
) : ViewModel() {

    enum class Mode { OPEN, CLOSE }

    private val mode: Mode = savedStateHandle.get<String>(EXTRA_ACTION)?.let { Mode.valueOf(it) } ?: Mode.OPEN
    private val presetRoomId: Long? = savedStateHandle.get<Long?>(EXTRA_ROOM_ID)
    private val expectedLockNfcId: String? = savedStateHandle.get<String>(EXTRA_LOCK_NFC_ID)
    // 密码尝试列表，按优先级排序
    private val passwordList = NfcConfig.getPasswordList()
    private var currentPasswordIndex = 0
    private val selectedPassword: String = savedStateHandle.get<String>(EXTRA_PASSWORD) ?: passwordList[0]
    private var lockPasswordKey: ByteArray = buildPasswordKey(selectedPassword)

    init {
        android.util.Log.d("NfcOperationViewModel", "Initialized with password: $selectedPassword")
        android.util.Log.d("NfcOperationViewModel", "Password key length: ${lockPasswordKey.size}")
        android.util.Log.d("NfcOperationViewModel", "Available passwords: ${passwordList.joinToString()}")
        loadCurrentUser()
        loadRooms()
    }

    private var locationManuallySelected = false
    private var lastProcessedTag: String? = null
    private var currentUser: UserProfile? = null
    private var currentUserLoaded = false
    private var isLoadingUser = false
    private var successStateTimestamp: Long = 0
    private val SUCCESS_STATE_DURATION_MS = NfcConfig.SUCCESS_STATE_DURATION_MS

    private val _uiState = MutableLiveData(
        NfcOperationUiState(
            mode = mode,
            statusText = initialStatusText(mode)
        )
    )
    val uiState: LiveData<NfcOperationUiState> = _uiState

    init {
        loadCurrentUser()
        loadRooms()
    }

    fun selectRoom(roomId: Long?) {
        val rooms = _uiState.value?.rooms.orEmpty()
        val room = rooms.firstOrNull { it.roomId == roomId }
        _uiState.updateState { state ->
            val target = room ?: state.selectedRoom
            val latitude = when {
                locationManuallySelected -> state.latitude
                target?.latitude != null -> target.latitude
                else -> state.latitude
            }
            val longitude = when {
                locationManuallySelected -> state.longitude
                target?.longitude != null -> target.longitude
                else -> state.longitude
            }
            state.copy(
                selectedRoom = target,
                latitude = latitude,
                longitude = longitude,
                message = null
            )
        }
    }

    fun updateLocation(latitude: Double, longitude: Double) {
        locationManuallySelected = true
        _uiState.updateState { state ->
            state.copy(
                latitude = latitude,
                longitude = longitude,
                message = null
            )
        }
    }

    fun clearMessage() {
        _uiState.updateState { it.copy(message = null) }
    }
    
    fun resetToGuideState() {
        _uiState.updateState {
            it.copy(
                animationState = NfcOperationUiState.AnimationState.GUIDE,
                statusText = initialStatusText(mode),
                result = null,
                message = null,
                isProcessing = false,
                chargeProgress = null
            )
        }
    }

    fun onTagDetected(tag: Tag) {
        android.util.Log.d("NfcOperationViewModel", "Tag detected: ${tag.id?.joinToString(separator = "") { "%02X".format(it) }}")
        val tagId = tag.id?.joinToString(separator = "") { "%02X".format(it) } ?: run {
            android.util.Log.e("NfcOperationViewModel", "Tag ID is null or unreadable")
            _uiState.updateState {
                it.copy(
                    statusText = "Unreadable tag, please retry",
                    message = "Unreadable tag, please retry",
                    result = false,
                    showAddLockPrompt = false,
                    pendingLockNfcId = null,
                    addLockInProgress = false
                )
            }
            return
        }
        val current = _uiState.value ?: return
        if (current.isProcessing || current.addLockInProgress) return
        // 如果是同一个标签且操作成功，在成功状态持续期间不重新处理
        if (tagId == lastProcessedTag && current.result == true && !current.showAddLockPrompt) {
            val currentTime = System.currentTimeMillis()
            if (currentTime - successStateTimestamp < SUCCESS_STATE_DURATION_MS) {
                android.util.Log.d("NfcOperationViewModel", "Same tag detected with success result, keeping current state for ${SUCCESS_STATE_DURATION_MS - (currentTime - successStateTimestamp)}ms more")
                return
            }
        }
        
        // 如果当前处于成功状态且时间未到，不处理新的标签检测
        if (current.animationState == NfcOperationUiState.AnimationState.SUCCESS && 
            current.result == true &&
            System.currentTimeMillis() - successStateTimestamp < SUCCESS_STATE_DURATION_MS) {
            android.util.Log.d("NfcOperationViewModel", "Ignoring tag detection during success state display")
            return
        }

        if (!currentUserLoaded) {
            if (!isLoadingUser) {
                loadCurrentUser()
            }
            _uiState.updateState {
                it.copy(
                    isProcessing = false,
                    statusText = "Loading account info, please retry shortly",
                    message = "Loading account info, please retry shortly",
                    result = false,
                    chargeProgress = null,
                    showAddLockPrompt = false,
                    pendingLockNfcId = null,
                    addLockInProgress = false
                )
            }
            return
        }

        expectedLockNfcId?.let { expected ->
            if (!expected.equals(tagId, ignoreCase = true)) {
                _uiState.updateState {
                    it.copy(
                        statusText = "Detected unexpected tag ",
                        message = "Please use tag  for this lock",
                        result = false,
                        showAddLockPrompt = false,
                        pendingLockNfcId = null,
                        addLockInProgress = false
                    )
                }
                return
            }
        }

        val room = current.selectedRoom
        if (room == null) {
            _uiState.updateState {
                it.copy(
                    statusText = "Please choose a room",
                    message = "Select a room before operating the lock",
                    result = false
                )
            }
            return
        }

        if (!hasPermissionForRoom(room)) {
            _uiState.updateState {
                it.copy(
                    statusText = "No permission for this lock",
                    message = "Current account is not allowed to operate this lock",
                    result = false,
                    showAddLockPrompt = false,
                    pendingLockNfcId = null,
                    addLockInProgress = false,
                    chargeProgress = null
                )
            }
            return
        }

        val latitude = current.latitude
        val longitude = current.longitude
        if (latitude == null || longitude == null) {
            _uiState.updateState {
                it.copy(
                    statusText = "Missing location information",
                    message = "Confirm current location or choose the room location",
                    result = false
                )
            }
            return
        }

        _uiState.updateState {
            it.copy(
                isProcessing = true,
                statusText = "Validating lock information...",
                message = null,
                result = null,
                lastTagId = null,
                chargeProgress = null,
                showAddLockPrompt = false,
                pendingLockNfcId = null,
                addLockInProgress = false,
                animationState = NfcOperationUiState.AnimationState.GUIDE
            )
        }

        viewModelScope.launch {
            val access = findLockByNfcIdUseCase(tagId)
            when (access) {
                is LockAccessResult.Allowed -> {
                    val resolvedRoom = _uiState.value?.rooms
                        ?.firstOrNull { access.lock.roomId != null && it.roomId == access.lock.roomId }
                        ?: room
                    if (!hasPermissionForRoom(resolvedRoom)) {
                        _uiState.updateState {
                            it.copy(
                                isProcessing = false,
                                statusText = "No permission for this lock",
                                message = "Current account is not allowed to operate this lock",
                                result = false,
                                chargeProgress = null,
                                showAddLockPrompt = false,
                                pendingLockNfcId = null,
                                addLockInProgress = false
                            )
                        }
                        return@launch
                    }
                    lastProcessedTag = tagId
                    _uiState.updateState {
                        it.copy(
                            selectedRoom = resolvedRoom,
                            isProcessing = true,
                            statusText = "Detected , preparing to ",
                            message = null,
                            result = null,
                            lastTagId = tagId,
                            chargeProgress = 0,
                            showAddLockPrompt = false,
                            pendingLockNfcId = null,
                            addLockInProgress = false
                        )
                    }
                    when (val hardware = performHardwareOperationWithRetry(tag, tagId)) {
                        is HardwareResult.Success -> {
                            handleBackendReport(tagId, resolvedRoom, latitude, longitude, hardware.deviceInfo)
                        }
                        is HardwareResult.Failure -> {
                            lastProcessedTag = null
                            _uiState.updateState {
                                it.copy(
                                    isProcessing = false,
                                    statusText = hardware.message,
                                    message = hardware.message,
                                    result = false,
                                    chargeProgress = null,
                                    showAddLockPrompt = false,
                                    pendingLockNfcId = null,
                                    addLockInProgress = false
                                )
                            }
                        }
                    }
                }
                is LockAccessResult.NotFound -> {
                    lastProcessedTag = null
                    if (!hasPermissionForRoom(room)) {
                        _uiState.updateState {
                            it.copy(
                                isProcessing = false,
                                statusText = "No permission for this lock",
                                message = "Current account is not allowed to operate this lock",
                                result = false,
                                chargeProgress = null,
                                showAddLockPrompt = false,
                                pendingLockNfcId = null,
                                addLockInProgress = false
                            )
                        }
                        return@launch
                    }
                    _uiState.updateState {
                        it.copy(
                            isProcessing = false,
                            statusText = "Lock not found in system",
                            message = "No lock found for tag , please register it",
                            result = false,
                            chargeProgress = null,
                            showAddLockPrompt = true,
                            pendingLockNfcId = tagId,
                            addLockInProgress = false
                        )
                    }
                }
                is LockAccessResult.Forbidden -> {
                    lastProcessedTag = null
                    val hint = access.message ?: "Current account has no permission for this lock"
                    _uiState.updateState {
                        it.copy(
                            isProcessing = false,
                            statusText = hint,
                            message = hint,
                            result = false,
                            chargeProgress = null,
                            showAddLockPrompt = false,
                            pendingLockNfcId = null,
                            addLockInProgress = false
                        )
                    }
                }
                is LockAccessResult.Error -> {
                    lastProcessedTag = null
                    val hint = access.message ?: "Failed to validate lock information, please retry"
                    _uiState.updateState {
                        it.copy(
                            isProcessing = false,
                            statusText = hint,
                            message = hint,
                            result = false,
                            chargeProgress = null,
                            showAddLockPrompt = false,
                            pendingLockNfcId = null,
                            addLockInProgress = false
                        )
                    }
                }
            }
        }
    }

    private suspend fun handleBackendReport(
        tagId: String,
        room: Room,
        latitude: Double,
        longitude: Double,
        deviceInfo: NfcDeviceManager.DeviceInfo
    ) {
        val params = NfcOperationParams(
            lockNfcId = tagId,
            roomId = room.roomId,
            longitude = longitude,
            latitude = latitude,
            remark = buildRemark(room)
        )
        val response = when (mode) {
            Mode.OPEN -> openLockUseCase(params)
            Mode.CLOSE -> closeLockUseCase(params)
        }
        when (response) {
            is NetworkResult.Success -> {
                successStateTimestamp = System.currentTimeMillis() // 记录成功状态时间戳
                _uiState.updateState {
                    it.copy(
                        isProcessing = false,
                        statusText = "Operation completed successfully",
                        result = true,
                        message = "Operation completed successfully",
                        chargeProgress = null,
                        addLockInProgress = false,
                        animationState = NfcOperationUiState.AnimationState.SUCCESS
                    )
                }
            }
            is NetworkResult.Error -> {
                if (response.code == LOCK_NOT_EXIST_CODE) {
                    lastProcessedTag = null
                    _uiState.updateState {
                        it.copy(
                            isProcessing = false,
                            statusText = "Lock not found in system",
                            result = false,
                            message = "The lock is not registered, please register it first",
                            showAddLockPrompt = true,
                            pendingLockNfcId = tagId,
                            chargeProgress = null,
                            addLockInProgress = false
                        )
                    }
                } else {
                    val message = response.message ?: "Operation failed, please retry"
                    _uiState.updateState {
                        it.copy(
                            isProcessing = false,
                            statusText = message,
                            message = message,
                            result = false,
                            chargeProgress = null,
                            showAddLockPrompt = false,
                            pendingLockNfcId = null,
                            addLockInProgress = false,
                            animationState = NfcOperationUiState.AnimationState.OPERATION
                        )
                    }
                }
            }
            is NetworkResult.Loading -> Unit
        }
    }

    private suspend fun performHardwareOperation(tag: Tag, tagId: String): HardwareResult {
        android.util.Log.d("NfcOperationViewModel", "Starting hardware operation for tag: $tagId with password: ${passwordList[currentPasswordIndex]}")
        val nfcA = NfcA.get(tag) ?: run {
            android.util.Log.e("NfcOperationViewModel", "NFC-A not supported for tag: $tagId")
            return HardwareResult.Failure("Unsupported tag protocol")
        }
        val manager = NfcDeviceManager(nfcA)
        return try {
            android.util.Log.d("NfcOperationViewModel", "Initializing device manager...")
            val (initResult, device) = manager.init()
            if (initResult != DeviceResult.OK || device == null) {
                android.util.Log.e("NfcOperationViewModel", "Device initialization failed: $initResult")
                return HardwareResult.Failure("Failed to initialise the lock, please retry")
            }
            val (infoResult, info) = manager.getInfo(device)
            if (infoResult != DeviceResult.OK || info == null) {
                return HardwareResult.Failure("Failed to read lock info, please retry")
            }
            val workKey = manager.deriveWorkKey(lockPasswordKey, info)
            
            // 开始充电动画 - 类似小程序端的实现
            _uiState.updateState { state ->
                state.copy(
                    animationState = NfcOperationUiState.AnimationState.CHARGING,
                    statusText = "Charging lock...",
                    chargeProgress = 0
                )
            }
            
            // 轮询充电进度，最多尝试40次（与小程序完全一致）
        var controlSuccessful = false
        for (attempt in 1..MAX_CHARGE_ATTEMPTS) {
            android.util.Log.d("NfcOperationViewModel", "Checking charge progress (attempt $attempt/$MAX_CHARGE_ATTEMPTS)")
            val (chargeResult, chargeLevel) = manager.getChargeLevel(device, workKey)
            if (chargeResult != DeviceResult.OK || chargeLevel == null) {
                android.util.Log.e("NfcOperationViewModel", "Failed to get charge level: $chargeResult")
                return HardwareResult.Failure("Failed to get charging progress, please retry")
            }
            
            // 更新充电进度
            _uiState.updateState { state ->
                state.copy(
                    chargeProgress = chargeLevel.level,
                    statusText = "Charging ${chargeLevel.level}% (${attempt}/${MAX_CHARGE_ATTEMPTS})",
                    animationState = NfcOperationUiState.AnimationState.CHARGING
                )
            }
            
            // 充电完成条件判断（与小程序一致）
            if (chargeLevel.complete || chargeLevel.level >= 100) {
                android.util.Log.d("NfcOperationViewModel", "Charging complete, starting control operation...")
                
                // 开始操作动画
                _uiState.updateState { state ->
                    state.copy(
                        animationState = NfcOperationUiState.AnimationState.OPERATION,
                        statusText = if (mode == Mode.OPEN) "Opening lock..." else "Closing lock..."
                    )
                }
                
                val controlResult = manager.control(device, workKey, controlCommand(), NFC_USER_NAME)
                if (controlResult == DeviceResult.OK) {
                    android.util.Log.d("NfcOperationViewModel", "Control operation succeeded")
                    controlSuccessful = true
                    return HardwareResult.Success(info)
                } else {
                    android.util.Log.e("NfcOperationViewModel", "Control operation failed: $controlResult")
                    return HardwareResult.Failure("Lock refused the command, please retry")
                }
            }
            
            // 等待100ms后继续检查（与小程序完全一致）
            delay(CHARGE_INTERVAL_MS)
        }
            
            if (!controlSuccessful) {
                android.util.Log.w("NfcOperationViewModel", "Charging timeout after $MAX_CHARGE_ATTEMPTS attempts")
                return HardwareResult.Failure("Charging timed out, please retry")
            }
            
            HardwareResult.Failure("Charging timed out, please retry")
        } catch (ex: TagLostException) {
            android.util.Log.e("NfcOperationViewModel", "Tag lost during operation", ex)
            HardwareResult.Failure("Tag lost during operation, please retry")
        } catch (ex: Exception) {
            android.util.Log.e("NfcOperationViewModel", "Unexpected error during hardware operation", ex)
            HardwareResult.Failure(ex.message ?: "Unexpected error")
        } finally {
            manager.close()
        }
    }

    private suspend fun performHardwareOperationWithRetry(tag: Tag, tagId: String): HardwareResult {
        // 重置密码索引
        currentPasswordIndex = 0
        
        for (passwordIndex in passwordList.indices) {
            currentPasswordIndex = passwordIndex
            val currentPassword = passwordList[passwordIndex]
            lockPasswordKey = buildPasswordKey(currentPassword)
            
            android.util.Log.d("NfcOperationViewModel", "Trying password ${passwordIndex + 1}/${passwordList.size}: $currentPassword")
            
            _uiState.updateState {
                it.copy(
                    statusText = if (passwordIndex == 0) {
                        "Attempting to unlock with primary password..."
                    } else {
                        "Primary password failed, trying backup password..."
                    }
                )
            }
            
            val result = performHardwareOperation(tag, tagId)
            
            when (result) {
                is HardwareResult.Success -> {
                    android.util.Log.d("NfcOperationViewModel", "Password $currentPassword succeeded")
                    return result
                }
                is HardwareResult.Failure -> {
                    android.util.Log.d("NfcOperationViewModel", "Password $currentPassword failed: ${result.message}")
                    
                    // 如果是最后一个密码，返回失败
                    if (passwordIndex == passwordList.size - 1) {
                        // 所有密码都失败了，运行诊断
        android.util.Log.w("NfcOperationViewModel", "All passwords failed, running diagnostics...")
        val diagnosticReport = NfcDiagnostics.generateDiagnosticReport(tag)
        android.util.Log.w("NfcOperationViewModel", "Diagnostic status: ${diagnosticReport.status}")
        android.util.Log.w("NfcOperationViewModel", "Recommendations: ${diagnosticReport.recommendations.joinToString()}")
        
        val errorMessage = when (diagnosticReport.status) {
            com.sgcc.nfc.lock.core.nfc.DiagnosticStatus.OK -> 
                "All passwords failed. Please check lock configuration or contact administrator."
            else -> 
                "NFC communication issue detected: ${diagnosticReport.recommendations.firstOrNull() ?: "Unknown error"}"
        }
        
        return HardwareResult.Failure(errorMessage)
                    }
                    
                    // 如果不是密码错误（比如标签丢失、充电失败等），直接返回失败
                    if (result.message.contains("Tag lost") || 
                        result.message.contains("Charging") || 
                        result.message.contains("Failed to initialise") ||
                        result.message.contains("Failed to read")) {
                        return result
                    }
                    
                    // 继续尝试下一个密码
                    delay(500) // 短暂延迟后尝试下一个密码
                }
            }
        }
        
        return HardwareResult.Failure("All passwords failed. Please check if the lock is compatible or contact support.")
    }

    fun addPendingLock() {
        val state = _uiState.value ?: return
        val tagId = state.pendingLockNfcId ?: return
        val room = state.selectedRoom
        val roomId = room?.roomId
        if (roomId == null) {
            _uiState.updateState {
                it.copy(message = "Please choose a room before registering a lock")
            }
            return
        }

        _uiState.updateState {
            it.copy(
                addLockInProgress = true,
                message = null,
                statusText = "Registering lock...",
                isProcessing = false,
                chargeProgress = null
            )
        }

        viewModelScope.launch {
            try {
                val pendingNfcId = _uiState.value?.pendingLockNfcId ?: return@launch
                val selectedRoomId = _uiState.value?.selectedRoom?.roomId ?: return@launch
                
                when (val result = addLockUseCase(pendingNfcId, selectedRoomId)) {
                    is NetworkResult.Success -> {
                        lastProcessedTag = null
                        _uiState.updateState {
                            it.copy(
                                addLockInProgress = false,
                                showAddLockPrompt = false,
                                pendingLockNfcId = null,
                                statusText = "Lock registered, please tap the tag again to continue",
                                message = "Lock registered successfully. Tap the tag again to continue",
                                result = null,
                                chargeProgress = null
                            )
                        }
                    }
                    is NetworkResult.Error -> {
                        _uiState.updateState {
                            it.copy(
                                addLockInProgress = false,
                                statusText = "Registration failed",
                                message = result.message,
                                chargeProgress = null
                            )
                        }
                    }
                    is NetworkResult.Loading -> {
                        // 保持加载状态
                    }
                }
            } catch (e: Exception) {
                _uiState.updateState {
                    it.copy(
                        addLockInProgress = false,
                        statusText = "Registration failed",
                        message = e.message ?: "Failed to register lock",
                        chargeProgress = null
                    )
                }
            }
        }
    }

    private fun loadRooms() {
        viewModelScope.launch {
            when (val result = getRoomsUseCase(page = 1, pageSize = DEFAULT_ROOM_PAGE_SIZE)) {
                is NetworkResult.Success -> {
                    val rooms = result.data.data
                    _uiState.updateState { state ->
                        val selectedRoom = if (presetRoomId != null) {
                            rooms.find { it.roomId == presetRoomId }
                        } else {
                            state.selectedRoom
                        }
                        state.copy(
                            rooms = rooms,
                            selectedRoom = selectedRoom
                        )
                    }
                }
                is NetworkResult.Error -> {
                    _uiState.updateState { state ->
                        state.copy(
                            rooms = emptyList(),
                            selectedRoom = null,
                            message = "Failed to load rooms: ${result.message}"
                        )
                    }
                }
                is NetworkResult.Loading -> {
                    // Keep current state during loading
                }
            }
        }
    }

    private fun buildRemark(room: Room): String =
        "NFC--".take(100)

    private fun initialStatusText(mode: Mode): String =
        if (mode == Mode.OPEN) "Hold phone close to the lock to open" else "Hold phone close to the lock to close"

    private fun MutableLiveData<NfcOperationUiState>.updateState(transform: (NfcOperationUiState) -> NfcOperationUiState) {
        val current = value ?: NfcOperationUiState(mode = mode, statusText = initialStatusText(mode))
        val newState = transform(current)
        android.util.Log.d("NfcOperationViewModel", "State update: ${current.statusText} -> ${newState.statusText}, animationState: ${current.animationState} -> ${newState.animationState}")
        value = newState
    }

    private fun operationVerb(): String = if (mode == Mode.OPEN) "open" else "close"

    private fun controlCommand(): Control = if (mode == Mode.OPEN) Control.UNLOCK else Control.LOCK

    private fun buildPasswordKey(password: String): ByteArray {
        val raw = password.encodeToByteArray()
        return if (raw.size >= 16) {
            raw.copyOf(16)
        } else {
            ByteArray(16).also { buffer ->
                raw.copyInto(buffer)
            }
        }
    }

    private fun loadCurrentUser() {
        if (isLoadingUser || currentUserLoaded) return
        
        isLoadingUser = true
        viewModelScope.launch {
            when (val result = getProfileUseCase()) {
                is NetworkResult.Success -> {
                    currentUser = result.data
                    currentUserLoaded = true
                    isLoadingUser = false
                }
                is NetworkResult.Error -> {
                    currentUser = null
                    currentUserLoaded = true
                    isLoadingUser = false
                }
                is NetworkResult.Loading -> {
                    // Keep loading state
                }
            }
        }
    }

    private fun hasPermissionForRoom(room: Room?): Boolean {
        val user = currentUser ?: return false
        val role = RoleType.fromValue(user.roleType) ?: return false
        if (role == RoleType.SUPER_ADMIN || role == RoleType.PROVINCE_ADMIN) {
            return true
        }
        val userRegionId = user.regionId ?: return false
        val roomRegionId = room?.regionId ?: return false
        return userRegionId == roomRegionId
    }

    private sealed class HardwareResult {
        data class Success(val deviceInfo: NfcDeviceManager.DeviceInfo) : HardwareResult()
        data class Failure(val message: String) : HardwareResult()
    }

    companion object {
        const val EXTRA_ROOM_ID = "roomId"
        const val EXTRA_ACTION = "action"
        const val EXTRA_LOCK_NFC_ID = "lockNfcId"
        const val EXTRA_PASSWORD = "password"

        private const val DEFAULT_ROOM_PAGE_SIZE = 200
        private const val LOCK_NOT_EXIST_CODE = 4001

        private val MAX_CHARGE_ATTEMPTS = NfcConfig.MAX_CHARGE_ATTEMPTS
        private val CHARGE_INTERVAL_MS = NfcConfig.CHARGE_INTERVAL_MS
        private const val NFC_LOCK_PASSWORD = "123456"
        private const val NFC_USER_NAME = "user"
    }
}




